.TITLE TDSCH .IDENT /14.02/ ; ; Copyright (c) 1995-1999 by Mentec, Inc., U.S.A. ; All rights reserved. ; ; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED ; OR COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE. ; ; D. N. CUTLER 11-AUG-73 ; ; PREVIOUSLY MODIFIED BY: ; ; J. R. KAUFFMAN ; T. M. MARTIN ; B. S. MCCARTHY ; J. W. BERZLE ; L. B. MCCULLEY ; C. A. SILVER ; K. L. NOEL ; D. CARROLL ; ; Modified for RSX-11M-PLUS V4.6 by: ; ; D. Carroll 18-Oct-1995 14.00 ; DC404 - Include PSECT statment to allow ICB pool to be ; fully expanded during sysgen ; ; D. Carroll 01-Jul-1998 14.02 ; DC506 - Include the full algorithm for leap year support ; including century transition. ; ; ; TIME DEPENDENT SCHEDULING AND DEVICE TIME OUT ; ; MACRO LIBRARY CALLS ; .MCALL CLKDF$,HDRDF$,HWDDF$,TCBDF$,PCBDF$ .IF DF M$$PRO .MCALL BGCK$A ; Bugcheck macro .ENDC ;DF M$$PRO CLKDF$ ;DEFINE CLOCK QUEUE CONTROL BLOCK OFFSET HDRDF$ ;DEFINE TASK HEADER OFFSETS HWDDF$ ;DEFINE HARDWARE REGISTERS .IF DF R$$PRO .MCALL UPTUP$ ;UPTIME UPDATE .ENDC ; DF R$$PRO .IF DF N$$DIR .MCALL LNMDF$ LNMDF$ ;DEFINE CONTEXT BLOCK OFFSETS .ENDC ;DF N$$DIR TCBDF$ ;DEFINE TASK CONTROL BLOCK OFFSETS PCBDF$ ;DEFINE PARTITION CONTROL BLOCK OFFSETS .IIF DF,K$$DAS&I$$CBP, .PSECT EXEC1 ;DC404 ;DC404 ;+ ; **-$CKINT-CLOCK INTERRUPT ; ; THIS ROUTINE IS ENTERED AS THE RESULT OF A CLOCK INTERRUPT. $INTSV ; IS CALLED TO SAVE REGISTERS R4 AND R5 AND $INTCT IS INCREMENT. IF ; THE RESULT IS NONZERO, THEN A JUMP TO $INTXT IS EXECUTED. ELSE ; A FORK IS EXECUTED SO THAT PENDING CLOCK INTERRUPTS CAN BE PRO- ; CESSED. ;- $CKINT:: ;;;REFERENCE LABEL .IF NDF K$$DAS JSR R5,$INTSE ;;;CALL INTERRUPT SAVE ROUTINE .WORD ^C&PR7 ;;;NEW PRIORITY IS PR5 .IFF ; NDF K$$DAS MOV R5,-(SP) ;MIMIC ACTIONS OF $DIRSV TO PREVENT MOV R4,-(SP) ;WASTE TIME ON I/D SYSTEMS DEC $STKDP ;;;SWITCH STACKS ? 5$: BIC #^C&PR7,@#PS ;;;DROP TO DEVICE PRIORITY CACHE$ SAVE ;;;SAVE BYPASS STATE OF CACHE MOV #$INTSF,-(SP) ;;;PUSH ADDRESS OF EXEC EXIT ROUTINE .ENDC ; DF K$$DAS .IF DF K$$W11 MOV #103,K$$W11 ;;;ENABLE AND START TIMER .ENDC .IF DF P$$3XX TST @$CKCSA ;;;ENSURE CLOCK ISN'T LONESOM ;;;(IF WE'RE ON A PRO-3XX) .ENDC ; DF P$$3XX .IF DF M$$PRO CALL $STTIC ;UPDATE SANITY TIMER BIT $CKURM,@$CPURM ;DO WE MAINTAIN CLOCK? BEQ 7$ ;IF EQ NO -- EXIT .IFTF MOV #$INTCT,R4 ;;;POINT TO INTERRUPT COUNT INC (R4) ;;;INCREMENT INTERRUPT COUNT BEQ 10$ ;;;IF EQ FORK .IFT MOV $TKPS,R5 ;;; Get the ticks/second MUL #10.,R5 ;;; multiply * 10 CMP (R4),R5 ;;; are we in range? BLO 7$ ;;; if LO, yes, finish the interrupt ;+ ; If we cannot process a clock interrupt within 10 seconds, we are ; no longer processing in real time, and we may as well become ; a VAX ... Call an end to this ... NOW! ;- BGCK$A BF.SAN,BE.IDC, ;;; System massively confused 7$: ;;;REFERENCE LABEL .ENDC RETURN ;;;EXIT FROM INTERRUPT 10$: CALL $FORK0 ;;;EXECUTE FORK ; ; UPDATE ABSOLUTE AND REAL TIME OF DAY AND DATE ; ;+ ; ** W A R N I N G ** ; ; SPM HOOKPOINT NUMBER 67. ; ; DO NOT CHANGE THE INSTRUCTION FOLLOWING ; LABEL WITHOUT CHECKING SPM ;- $SPH67==. ;SPM CHANGES THE INSTRUCTION AT ;THE LOCATION OF THIS LABEL UPTIM: MOV #$TKPS+2,R4 ;POINT PAST CONVERSION VECTOR MOV #$TTNS+2,R5 ;POINT PAST CURRENT TIME VECTOR 10$: MOV #$TTNS-10,R2 ;POINT TO DAY INC -(R5) ;UPDATE A COUNTER CMP -(R4),(R5) ;EXCEEDED LIMIT? BHI 20$ ;IF HI NO CLR (R5) ;RESET COUNTER CMP R5,R2 ;CHECK FOR LAST DAY OR MONTH BHI 10$ ;IF HI NO INC (R5) ;DAY AND MONTH ARE 1 ORIGIN BCS 10$ ;IF CS NOT DAY MOV -(R2),R1 ;GET CURRENT MONTH MOVB $DYPMN-1(R1),R0 ;GET DAYS FOR NEXT MONTH PLUS 1 MOV R0,(R4) ;MOVE TO DAYS PER MONTH LIMIT DEC R1 ;IS CURRENT MONTH ENDING JANUARY? BNE 10$ ;IF NE NO BIT #3,-(R2) ;IS THIS A LEAP YEAR? BNE 10$ ;IF NE NO ;+ ;DC506 ; We have a potential leap year ... The current year is divisible ;DC506 ; by four, now to determine if it is divisible by 100. If not, ;DC506 ; this is a leap year, else next test ... ;DC506 ;- ;DC506 MOV (R2),R1 ; get the current year ;DC506 ADD #1900.,R1 ; correct for reality ;DC506 CLR R0 ; set up for divide ;DC506 DIV #100.,R0 ; determine if the leap year is / 100 ;DC506 TST R1 ; divisible by 100. ;DC506 BNE 15$ ; nope, has to be a leap year ;DC506 ;+ ;DC506 ; Now, we have a century ... is the century divisible by 400? If ;DC506 ; so, we have a leap year ... ;DC506 ;- ;DC506 BIT #3,R0 ; how about by 400. ;DC506 BNE 10$ ; if NE, nope, not a leap year ;DC506 15$: ;DC506 INC (R4) ;INCREMENT DAYS FOR FEBRUARY BR 10$ ; 20$: ;REFERENCE LABEL .IF DF R$$PRO DEC $NVRTM ;TIME TO UPDATE O/S UPTIME ? BNE 25$ ;IF NE NO UPTUP$ ;UPDATE UPTIME 25$: ;REFERENCE LABEL .ENDC ; DF R$$PRO TST $SHFTM ;SHF TIMER ALREADY EXPIRED ? BEQ 30$ ;IF EQ, YES DEC $SHFTM ;DECREMENT TIMER BLOCKING SHF REQUESTS 30$: INC $ABTIM ;UPDATE ABSOLUTE TIME COUNTER BNE TDS ;IF NE NO OVERFLOW INC $ABTIM-2 ;COUNT OVERFLOW IN SECOND WORD OF $ABTIM MOV #$CLKHD,R0 ;POINT TO CLOCK QUEUE LISTHEAD 40$: MOV (R0),R0 ;GET ADDRESS OF NEXT ENTRY BEQ TDS ;IF EQ NO MORE IN LIST DEC C.TIM+2(R0) ;ADJUST HIGH ORDER TIME BR 40$ ; ; ; TIME DEPENDENT SCHEDULING ; TDS: ;REFERENCE LABEL .IF DF M$$PRO MOV KISAR6,-(SP) ;SAVE MAPPING POINTER CLR KISAR6 ;POINT TO REAL ZERO INC @#140110 ;BUMP ABSOLUTE LOCATION 110 MOV (SP)+,KISAR6 ;RESTORE MAPPING POINTER .IFF INC @$CKINC ;BUMP TICKER ;ABSOLUTE LOCATION 110 OR TPR5 IF CPR ON KXJ-11 .ENDC MOV $CLKHD,R4 ;GET ADDRESS OF NEXT IN QUEUE BEQ 11$ ;IF EQ, NONE IN LIST TST C.TIM+2(R4) ;HIGH ORDER PART NONZERO? BNE 11$ ;IF NE, YES CMP $ABTIM,C.TIM(R4) ;TIME TO GO? BLO 11$ ;IF LO, NO MOV (R4),$CLKHD ;REMOVE ENTRY FROM CLOCK QUEUE MOVB C.RQT(R4),R5 ;GET ENTRY REQUEST TYPE ADD R5,PC ;DISPATCH TO PROCESSING ROUTINE 10$: BR 20$ ;MARK TIME REQUEST BR 30$ ;TASK REQUEST WITH PERIODIC RESCHEDULE BR 30$ ;SINGLE SHOT TASK REQUEST BR 12$ ;SINGLE SHOT INTERNAL SUBROUTINE (C.SYST) BR 15$ ;SINGLE SHOT INTERNAL SUBROUTINE ; ; CLEAR STOP BIT AND REALLOCATE PARTITION ; MOV C.TCB(R4),R0 ;PICK UP TCB ADDRESS CALL $EXRQN ;CLEAR STOP BIT AND REALLOCATE PARTITION BR TDS ; 11$: JMP DVOUT ;JUMP TO DEVICE TIMOUT ; ; SINGLE SHOT INTERNAL SUBROUTINE (TYPE 6) ; ; THIS SECTION HANDLES URM SPECIFIC CLOCK BLOCKS 12$: ;REFERENCE LABEL .IF DF M$$PRO MOV #TDS,-(SP) ;PUSH RETURN ADDRESS FROM EITHER DRIVER ;(IF WE'RE NOW ON CORRECT CPU) OR $FORK0 ;(IF WE'RE NOT) BIT C.URM(R4),@$CPURM ;ARE WE ALREADY ON CORRECT PROCESSOR BNE 17$ ;IF NE YES, GO CALL THE DRIVER AND ;CONTINUE CLQ SCAN TST (R4)+ ;POINT PAST LINK WORD MOV C.URM-C.RQT(R4),(R4)+ ;PUT URM IN CORRECT PLACE CMP (R4)+,(R4)+ ;POINT PAST LINK AND PC IN FORK BLOCK CALL $FORK0 ;GET TO RIGHT PROCESSOR MOV R3,R4 ;COPY FORK BLOCK POINTER SUB #C.TIM,R4 ;POINT BACK TO BEGINNING OF CLOCK BLOCK BR 17$ ;GO MAP DRIVER AND CALL ; ; SINGLE SHOT INTERNAL SUBROUTINE (TYPE 8, ALSO TYPE 6 ON UNIPROCESSOR) ; .IFTF ;DF M$$PRO 15$: ;REFERENCE LABEL .IFT ;DF M$$PRO MOV #TDS,-(SP) ;PUSH RETURN ADDRESS TO SCAN CLQ AGAIN .IFTF ;DF M$$PRO 17$: MOV KINAR5,-(SP) ;SAVE KERNEL INSTR ADDR REG 5 .IF DF K$$DAS MOV KDSAR5,-(SP) ;SAVE KERNEL DATA ADDR REG 5 MOV C.AR5(R4),KDSAR5 ;MAP DRIVER IN DATA SPACE .IFTF MOV C.AR5(R4),KINAR5 ;MAP DRIVER IN INSTR SPACE ;+ ; ** W A R N I N G ** ; ; SPM HOOKPOINT NUMBER 66. ; ; DO NOT CHANGE THE INSTRUCTION FOLLOWING ; LABEL WITHOUT CHECKING SPM ;- $SPH66==. ;SPM CHANGES THE INSTRUCTION AT ;THE LOCATION OF THIS LABEL CALL @C.SUB(R4) ;CALL SYSTEM SUBROUTINE .IFT MOV (SP)+,KDSAR5 ;RESTORE KERNEL DATA ADDR REG 5 .ENDC MOV (SP)+,KINAR5 ;RESTORE KERNEL INSTR ADDR REG 5 .IFT ;DF M$$PRO RETURN ; .IFF ;DF M$$PRO BR TDS ; .ENDC ;DF M$$PRO ; ; MARK TIME REQUEST ; 20$: MOV C.SRC(R4),R0 ;PICK UP EVENT FLAG MASK WORD MOV C.DST(R4),R1 ;PICK UP EVENT FLAG MASK ADDRESS MOV C.TCB(R4),R5 ;PICK UP TCB ADDRESS CALL $SETMG ;SET EFN AND UNLOCK IF GROUP GLOBAL CLR R5 ;RESET CLOCK BLOCK TYPE MOV C.AST(R4),R3 ;GET AST TRAP ADDRESS BEQ 40$ ;IF EQ NO AST SPECIFIED MOVB C.EFN(R4),R2 ;GET EFN NUMBER MOV R4,R1 ;COPY ADDRESS OF CLOCK QUEUE ENTRY TST (R4)+ ;POINT TO CONTROL BLOCK LENGTH MOV #C.LGTH,(R4)+ ;SET LENGTH OF AST CONTROL BLOCK MOV #8.*2,(R4)+ ;SET BYTES TO ALLOCATE ON TASK STACK MOV R3,(R4)+ ;INSERT AST TRAP ADDRESS MOV #1,(R4)+ ;SET NUMBER OF AST PARAMETERS MOV R2,(R4) ;INSERT EFN AS AST PARAMETER CALL $QASTT ;QUEUE AST TO TASK BR TDS ; ; ; SCHEDULE REQUEST ; 30$: MOV C.TCB(R4),R0 ;GET TASK TCB ADDRESS .IF NDF N$$DIR MOV C.UIC(R4),R1 ;GET REQUEST UIC .IFF TSTB C.NAM(R4) ;IS THERE A UIC OR CTX BNE 35$ ;IF NE, GET UIC FROM CONTEXT BLOCK MOV C.UIC(R4),R1 ;GET REQUEST UIC BR 37$ ; 35$: MOV C.CTX(R4),R1 ;GET CONTEXT BLOCK POINTER MOV KISAR6,-(SP) ;SAVE CURRENT MAPPING MOV R1,KISAR6 ;MAP CONTEXT BLOCK TSTB C.DDSL+140000 ;IS THERE A DDS? BEQ 36$ ;IF EQ, DON'T PROPAGATE MOV R1,$CTXPT ;PROPAGATE CONTEXT BLOCK 36$: MOV C.CUIC+140000,R1;GET REQUEST UIC MOV (SP)+,KISAR6 ;RESTORE MAPPING 37$: ;REFERENCE LABEL .ENDC ;NDF N$$DIR .IF DF A$$CNT MOV C.UAB(R4),$CKUAB ;GET UAB TO BILL TASK TO .IFTF CALL $TSKRT ;REQUEST TASK EXECUTION .IFT CLR $CKUAB ;DO NOT NEED UAB ADDRESS ANYMORE .ENDC 40$: MOV R4,R0 ;SET ADDRESS OF BLOCK TO RELEASE CMPB #C.SCHD,R5 ;PERIODIC REQUEST? BEQ 50$ ;IF EQ YES CALL $DCLKA ;DEALLOCATE CLQ BLOCK WITH ACCOUNTING JMP TDS ; 50$: MOV C.RSI+2(R0),R1 ;SET HIGH ORDER PART OF TIME MOV C.RSI(R0),R2 ;SET LOW ORDER PART OF TIME MOV R5,R4 ;SET REQUEST TYPE .IF DF N$$DIR TSTB C.NAM(R0) ;IS THERE A UIC OR CTX BEQ 55$ ;IF EQ, NO CONTEXT BLOCK POINTER BIS #100000,R4 ;SET HIGH BIT TO INDICATE CTX PTR 55$: ;REFERENCE LABEL .ENDC ;DF N$$DIR MOV C.TCB(R0),R5 ;SET ADDRESS OF REQUEST TASK TCB CALL $CLINS ;REINSERT ENTRY IN CLOCK QUEUE JMP TDS ; ; ; DEVICE TIME OUT ; DVOUT: TST $TTNS ;ONE SECOND ELAPSED? BNE ROBIN ;IF NE NO MOV #$SCDVT,-(SP) ;SET ADDRESS OF DEVICE TABLE SCANNING CO-ROUTINE 10$: CALL @(SP)+ ;GET NEXT UCB ADDRESS BCS ROBIN ;IF CS END OF TABLE MOV S.KRB(R4),R2 ;GET KRB ADDRESS BEQ 11$ ;IF EQ NO KRB MTPS K.PRI(R2) ;;;SET THE DEVICE PRIORITY 11$: TSTB U.STS(R5) ;;;UNIT BUSY? BPL 20$ ;;;IF PL NO TSTB S.CTM(R4) ;;;TIMEOUT ACTIVE? BEQ 20$ ;IF EQ NO .IF DF M$$PRO CMPB #377,S.CTM(R4) ;WAITING FOR INTERPROCESSOR FORK ? BEQ 20$ ;IF EQ YES, DON'T TOUCH INTERLOCK .ENDC ; DF M$$PRO DECB S.CTM(R4) ;;;DECREMENT TIMEOUT COUNT BNE 20$ ;;;IF NE -- MORE TIME TO GO ; ; DRIVER HAS TIMED OUT. CALL HIM AT HIS TIMEOUT ENTRY. ; .IF DF M$$PRO DECB S.CTM(R4) ;;;SET TIMED OUT FLAG FOR LATER MOV #12$,R3 ;;;SET UP FOR $EXDOP CALL $EXDOP ;;;CALL ROUTINE TO CALL DRIVER ; ; AT THIS POINT, IF DOESNT HAVE A KRB ADDRESS, THEN HE WAS CALLED ; BECAUSE OF THE WAY $EXDOP WORKS. ; 20$: MTPS #0 ;;;LOWER PRIORITY BR 10$ ;GO BACK FOR MORE ; ; INTERNAL SUBROUTINE TO CALL DRIVER AT HIS TIMEOUT ENTRY. ; THIS SUBROUTINE IS EXECUTED ON THE CPU TO WHICH THE DRIVER ; IS ATTACHED. ; 12$: MOV (R5),R3 ;RESTORE DCB ADDRESS MOV S.KRB(R4),R2 ;GET KRB ADDRESS BEQ 13$ ;IF EQ NO KRB MTPS K.PRI(R2) ;SET DEVICE PRIORITY 13$: TSTB U.STS(R5) ;;;UNIT STILL BUSY? BPL 30$ ;;;IF PL NO -- DON'T CALL HIM TSTB S.CTM(R4) ;;;DO WE STILL SHOW HIM TIMED OUT? BPL 30$ ;;;IF PL NO -- DON'T CALL HIM CLRB S.CTM(R4) ;;;SHOW HIM TIMED OUT .ENDC MOV #IE.DNR&377,R0 ;;;SET DEVICE NOT READY STATUS FOR DRVR MOV D.DSP(R3),R1 ;;;GET ADDRESS OF DRIVER DISPATCH TABLE MOV KINAR5,-(SP) ;;;SAVE KERNEL INSTR ADDR REG 5 .IF DF K$$DAS MOV KDSAR5,-(SP) ;;;SAVE KERNEL DATA ADDR REG 5 .IFTF MOV D.PCB(R3),R3 ;;;GET DRIVER PCB ADDRESS BEQ 15$ ;;;IF EQ DRIVER IS PART OF EXEC MOV P.REL(R3),KINAR5 ;;;MAP THE DRIVER IN INSTR SPACE .IFT MOV P.REL(R3),KDSAR5 ;;;MAP THE DRIVER IN DATA SPACE .IFTF 15$: TST R2 ;;;IS THERE A KRB ADDRESS BEQ 17$ ;;;IF EQ NO MOVB K.CON(R2),R3 ;;;GET CONTROLLER INDEX MOV (R2),R2 ;;;GET CSR ADDRESS ; ; CALL DRIVER AT TIMEOUT ENTRY POINT WITH THE ARGUMENTS: ; ; R0=DEVICE TIMEOUT STATUS 'IE.DNR'. ; R2=ADDRESS OF DEVICE CSR. ; R3=CONTROLLER INDEX. ; R4=ADDRESS OF THE STATUS CONTROL BLOCK. ; R5=ADDRESS OF THE UNIT CONTROL BLOCK. ; ; IF S.KRB=0 THEN R2, R3 ARE UNDEFINED ; ;+ ; ** W A R N I N G ** ; ; SPM HOOKPOINT NUMBER 64. ; ; DO NOT CHANGE THE INSTRUCTION FOLLOWING ; LABEL WITHOUT CHECKING SPM ;- $SPH64==. ;SPM CHANGES THE INSTRUCTION AT ;THE LOCATION OF THIS LABEL 17$: CALL @D.VOUT(R1) ;;;ENTER DRIVER .IFT MOV (SP)+,KDSAR5 ;;;RESTORE KERNEL DATA ADDR REG 5 .ENDC MOV (SP)+,KINAR5 ;;;RESTORE KERNEL INSTR ADDR REG 5 .IF DF M$$PRO 30$: MTPS #0 ;;;ALLOW INTERRUPTS RETURN .IFF 20$: MTPS #0 ;;;ALLOW INTERRUPTS BR 10$ ;GO FOR SOME MORE .ENDC ; ; EXECUTIVE LEVEL ROUND ROBIN SCHEDULING ; ROBIN: ;REF LABEL .IF DF R$$NDC DEC $RNDCT ;TIME TO SCHEDULE? BNE SWAP ;IF NE NO MOV $RNDC,$RNDCT ;RESET CLOCK TICKS TO NEXT INTERVAL MOV #SWAP,-(SP) ;ASSUME DIRECT EXIT TO DISK SWAP .IF DF M$$PRO MOV #60$,-(SP) ;THIS WILL PREVENT MULTIPLE CALLS ;TO $DRDSE IF MULTIPLE RUNNING TASKS ;ARE MOVED. .ENDC ; DF M$$PRO MOV #$ACTHD-T.ACTL,R1 ;SET ADDRESS OF PREVIOUS ENTRY 10$: MOV R1,R0 ;SAVE ADDRESS OF PREVIOUS ENTRY MOV T.ACTL(R0),R1 ;GET ADDRESS OF NEXT ENTRY BEQ 60$ ;IF EQ END OF LIST CMPB $RNDH,T.PRI(R1) ;PRIORITY IN RANGE? BLO 10$ ;IF LO NO 20$: CMPB $RNDL,T.PRI(R1) ;PRIORITY IN RANGE? BHI 60$ ;IF HI NO .IF NDF M$$PRO TST T.STAT(R1) ;TASK BLOCKED? .IFF BIT #^CTS.RUN,T.STAT(R1) ;TASK BLOCKED? .ENDC BNE 30$ ;IF NE YES BIT #T2.SPN!T2.STP!T2.WFR,T.ST2(R1) ; BEQ 40$ ;IF EQ NO 30$: MOV R1,R0 ;SAVE ADDRESS OF LAST ENTRY MOV T.ACTL(R0),R1 ;GET ADDRESS OF NEXT ENTRY BR 20$ ; 40$: TST T.ACTL(R1) ;NULL TASK? BEQ 60$ ;IF EQ YES .IF NDF M$$PRO CMP R1,$TKTCB ;ABOUT TO MOVE CURRENT TASK? BNE 45$ ;IF NE NO MOV #$DRDSE,-(SP) ;FORCE SIGNIFICANT EVENT AT END .IFF ; NDF M$$PRO BIT #TS.RUN,T.STAT(R1) ;TASK RUNNING ON SOME PROCESSOR BEQ 45$ ;IF EQ NO MOV #$DRDSE,(SP) ;FORCE SIGNIFICANT EVENT AT END .ENDC ; DF M$$PRO 45$: MOV T.ACTL(R1),T.ACTL(R0) ;REMOVE TCB FROM TASK LIST MOV R1,R2 ;SAVE ADDRESS OF TCB MOV R0,R1 ;SET ADDRESS OF LAST ENTRY 50$: MOV R1,R0 ;SAVE ADDRESS OF LAST ENTRY MOV T.ACTL(R0),R1 ;GET ADDRESS OF NEXT ENTRY CMPB T.PRI(R1),T.PRI(R2) ;IN SAME PRIORITY CLASS? BEQ 50$ ;IF EQ YES MOV R2,T.ACTL(R0) ;SET ADDRESS OF NEXT IN LAST MOV R1,T.ACTL(R2) ;SET ADDRESS OF NEXT IN REMOVED ENTRY MOV R2,R0 ;SET ADDRESS OF LAST ENTRY BR 20$ ; 60$: RETURN ;TO SWAP, WITH POSSIBLE INTERMEDIATE ;STOP AT $DRDSE .ENDC ; ; DISK SWAPPING ALGORITHM - REDUCE SWAPPING PRIORITY OF RESIDENT TASKS ; SWAP: ;REF LABEL .IF DF S$$WPC DEC $SWPCT ;TIME TO MODIFY SWAPPING PRIORITIES? BNE 70$ ;IF NE NO MOV $SWPC,$SWPCT ;RESET CLOCK TICKS TO NEXT SWAP INTERVAL MOV $PARHD,R5 ;POINT TO PARTITION LIST LISTHEAD 10$: TST P.SUB(R5) ;ANY MORE SUBPARTITIONS? BEQ 20$ ;IF EQ NO MOV P.SUB(R5),R5 ;POINT TO NEXT SUBPARTITION PCB BIT #PS.FXD!PS.CHK!PS.CKP!PS.CKR!PS.OUT!PS.COM,P.STAT(R5) ; BNE 10$ ;IF NE NOT CHECKPOINTABLE RESIDENT TASK MOV P.HDR(R5),R4 ;POINT TO TASK HEADER .IF DF X$$HDR BNE 15$ ;IF NE RESIDENT HEADER MOV P.REL(R5),KISAR6 ;MAP TO EXTERNAL HEADER MOV #140000,R4 ;AND POINT TO IT .IFTF ; DF X$$HDR 15$: CLR R0 ;CALCULATE THE MINIMUM SWAPPING PRIORITY SUB $SWPR,R0 ; .ENDC ; DF X$$HDR CMPB H.SPRI(R4),R0 ;SWAPPING PRIORITY AT MINIMUM? BLE 10$ ;IF LE YES DECB H.SPRI(R4) ;REDUCE SWAPPING PRIORITY BR 10$ ; 20$: MOV P.MAIN(R5),R5 ;POINT BACK TO MAIN PCB MOV R5,R0 ;COPY MAIN PCB POINTER CALL $NXTSK ;ATTEMPT TO REALLOCATE PARTITION MOV (R5),R5 ;POINT TO NEXT MAIN PCB BNE 10$ ;IF NE THERE IS ONE 70$: ;REF LABEL .ENDC ; ; EXIT TIME DEPENDENT SCHEDULE IF THERE ARE NOT REMAINING UNPROCESSED CLOCK TICK ; TIMXT: DEC $INTCT ;ANY MORE TICKS TO PROCESS? BGE 10$ ;IF GE YES RETURN ; 10$: JMP UPTIM ; ;+ ; **-$NLTMO-NULL TIMEOUT ROUTINE ; ; THIS ROUTINE MAY BE SPECIFIED AS THE TIMEOUT ROUTINE IN A DRIVER'S ; DISPATCH TABLE. IT SIMPLY BYPASSES ALL UNITS ON THE CURRENT DCB WHEN ; CALLED. ; ; INPUTS: ; ; AS FOR NORMAL DRIVER TIMEOUT ROUTINE. ; ; OUTPUTS: ; ; CURRENT DCB IS NO LONGER CONSIDERED FOR CURRENT TIMEOUT SCAN. ;- $NLTMO:: ;REFERENCE LABEL .IF DF K$$DAS CLR S$$SPC+4(SP) ;FORCE $SCDVT ON TO NEXT DCB .IFF ; DF K$$DAS CLR S$$SPC+2(SP) ;FORCE $SCDVT ON TO NEXT DCB .ENDC ; DF K$$DAS INCB S.CTM(R4) ;RESET TIMEOUT COUNT FOR NEXT TIME RETURN ; .END